package org.smileface.designpattern.prototype;


import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * @description: 原型模式工具类
 * @author: chujian
 * @since: 2022-02-19 16:23
 **/
@SuppressWarnings("unchecked")
public class PrototypeUtils {

    /**
     * 浅克隆
     *
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> T clone(T obj) {
        if (null == obj) return null;
        Object newInstance = null;
        try {
            newInstance = obj.getClass().getConstructor().newInstance();
            BeanUtils.copyProperties(obj, newInstance);
            return (T) newInstance;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 深度克隆
     *
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> T deepClone(T obj) {
        if (null == obj) return null;
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);

            Object o = ois.readObject();
            return (T) o;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 深度克隆，通过Json序列化的方式
     *
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> T deepCloneByJson(T obj) {
        String jsonString = JSON.toJSONString(obj);
        Object object = JSON.parseObject(jsonString, obj.getClass());
        return (T) object;
    }


}
